﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Abp.BackgroundJobs;
using Abp.Dependency;
using Abp.IO.Extensions;
using Abp.Runtime.Session;
using NUglify.JavaScript.Syntax;
using pandx.Mulan.Authorization.Users.Importing;
using pandx.Mulan.Authorization.Users.Importing.Dto;
using pandx.Mulan.Folders;
using pandx.Mulan.Storage;

namespace pandx.Mulan.Helpers
{
    public class FileUploadHelper : ITransientDependency
    {
        private readonly IAppFolder _appFolder;
        private readonly IBinaryObjectManager _binaryObjectManager;
        private readonly IBackgroundJobManager _backgroundJobManager;
        private readonly IAbpSession _abpSession;

        public FileUploadHelper(IAppFolder appFolder,IBinaryObjectManager binaryObjectManager,IBackgroundJobManager backgroundJobManager,IAbpSession abpSession)
        {
            _appFolder = appFolder;
            _binaryObjectManager = binaryObjectManager;
            _backgroundJobManager = backgroundJobManager;
            _abpSession = abpSession;
        }

     

        public async Task UploadPartialFile(Microsoft.AspNetCore.Http.HttpContext context,
            List<UploadFileResult> results, SaveType
                saveType)
        {
            var request = context.Request;
            var content_disposition = request.Headers["Content-Disposition"];
            var content_range = request.Headers["Content-Range"];
            var file = request.Form.Files[0];
            var inputStream = file.OpenReadStream();
            var fileName =
                System.Net.WebUtility.UrlDecode(content_disposition.ToString().Split(';')[2].Split('=')[1]
                    .Replace("\"", ""));
            string fullName =
                Path.Combine(_appFolder.TempFolder, fileName);
            using (var fileStream = new FileStream(fullName, FileMode.Append, FileAccess.Write))
            {
                var buffer = new byte[1024];
                var length = await inputStream.ReadAsync(buffer, 0, 1024);
                while (length > 0)
                {
                    await fileStream.WriteAsync(buffer, 0, length);
                    length = await inputStream.ReadAsync(buffer, 0, 1024);
                }

                await fileStream.FlushAsync();
            }

            if (!string.IsNullOrEmpty(content_disposition))
            {
                long fullSize = Convert.ToInt64(content_range[0].Split('/')[1]);
                long currentSize = Convert.ToInt64(content_range[0].Split('/')[0].Split('-')[1]);
                if (currentSize == fullSize)
                {
                    if (saveType == SaveType.A)
                    {
                    
                        var savedName = Guid.NewGuid().ToString();
                  
                        File.Move(fullName,
                            Path.Combine(_appFolder.BigFilesFolder, savedName + Path.GetExtension(fileName)));
                        results.Add(new UploadFileResult
                        {
                            OriginalFileName = fileName,
                            SavedFileName = savedName + Path.GetExtension(fileName),
                            FileSize = fullSize,
                            ContentType = file.ContentType
                        });
                    }

                    if (saveType == SaveType.B)
                    {
                        byte[] fileBytes;
                        using (var stream = new FileStream(fullName, FileMode.Open))
                        {
                            fileBytes = stream.GetAllBytes();
                        }
                        
                        var tenantId = _abpSession.TenantId;
                        
                        var fileObject = new BinaryObject(tenantId, fileBytes, $"{DateTime.UtcNow} 从Excel导出的文件");

                        await _binaryObjectManager.SaveAsync(fileObject);

                        await _backgroundJobManager.EnqueueAsync<ImportUsersFromExcelJob, ImportUsersFromExcelJobArgs>(
                            new ImportUsersFromExcelJobArgs
                            {
                                TenantId = tenantId,
                                BinaryObjectId = fileObject.Id,
                                User = _abpSession.ToUserIdentifier()
                            });
                        results.Add(new UploadFileResult
                        {
                            OriginalFileName = fileName,
                            SavedFileName = fileObject.Id.ToString(),
                            FileSize = fullSize,
                            ContentType = file.ContentType
                        });
                    }
                }
            }
        }
    }

    public class UploadFileResult
    {
        public string OriginalFileName { get; set; }
        public string SavedFileName { get; set; }
        public double FileSize { get; set; }
        public string ContentType { get; set; }
    }

    public enum SaveType
    {
        A,
        B,
        C
    }
}